package com.ruoyi.framework.propertySourcesEnc;

import com.ruoyi.common.utils.security.RsaUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

@Slf4j
@Configuration
public class EncryptConfig {

    public static final String PWD_PREFIX = "jasypt.encryptor.property.prefix";
    public static final String PWD_SUFFIX = "jasypt.encryptor.property.suffix";
    private static final String PUBLICKEY_WORD = "spring.datasource.druid.publicKey";
    private static final String PASSWD_WORD = "spring.datasource.druid.master.password";

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(ConfigurableEnvironment environment, EncryptionAwareService encryptionAwareService) {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new EncryptionAwarePropertySourcesPlaceholderConfigurer(encryptionAwareService);
        propertySourcesPlaceholderConfigurer.setEnvironment(environment);
//        propertySourcesPlaceholderConfigurer.setPropertySources(environment.getPropertySources());
        return propertySourcesPlaceholderConfigurer;
    }

    /**
     * This is just a demo impl of the bean. Write your own implementation of {@link EncryptionAwareService} and return that service as bean here.
     *
     * @return
     */
    @Bean
    public static EncryptionAwareService encryptionAwareService(Environment environment) {
        return new EncryptionAwareService() {
            @Override
            public String tryDecrypt(String text) {
                if (canTxtDecrypted(text)) {
                    try {
                        String publicKey = environment.getProperty(PUBLICKEY_WORD);
                        Assert.hasText(publicKey, PUBLICKEY_WORD + " must not empty");
                        String pwd_prefix_val = environment.getProperty(PWD_PREFIX);
                        String pwd_suffix_val = environment.getProperty(PWD_SUFFIX);
                        String passwd = text.substring(text.indexOf(pwd_prefix_val) + pwd_prefix_val.length(), text.indexOf(pwd_suffix_val));
                        String actualPasswd = RsaUtils.decryptByPublicKey(publicKey, passwd);
                        return actualPasswd;
//                        TextEncryptor encryptor = Encryptors.queryableText(environment.getProperty("app.somePassword"), environment.getProperty("app.someSalt"));
//                        return encryptor.decrypt(text.split(environment.getProperty(APP_SOME_ENC_PWD_PREFIX))[1]);
                    } catch (Exception e) {
                        log.error("EncryptionAwareService#tryDecrypt has error: {}", e);
                    }
                }
                return text;
            }

            // Whatever logic  you need to put to identify encrypted string
            @Override
            public boolean canTxtDecrypted(String text) {
                return StringUtils.hasText(text) //
                        && text.startsWith(environment.getProperty(PWD_PREFIX))//
                        && text.endsWith(environment.getProperty(PWD_SUFFIX));
            }
        };
    }
}